package org.ly817.my.spring.core.context;


import org.ly817.my.spring.core.ioc.bean.enhance.BeanPostProcessor;
import org.ly817.my.spring.core.ioc.factory.AbstractBeanFactory;

import java.util.List;

/**
 * 使用代理模式，控制beanFactory的生命周期
 *
 * Created by LuoYu on 2018/4/14.
 */
public abstract class AbstractApplicationContext implements ApplicationContext {

    protected AbstractBeanFactory beanFactory;

    public AbstractApplicationContext(AbstractBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    @Override
    public Object getBean(String name) throws Exception {
        return beanFactory.getBean(name);
    }

    /**
     * 封装加载bean元信息逻辑
     *
     * 具体实现由实现类决定
     * @see ClassPathApplicationContext
     *
     * ---------------
     * 拆分加载逻辑
     * - loadBeanDefinitions（加载元信息）
     * - registerBeanPostProcessors （提取注册到bean处理逻辑列表）
     * - onRefresh （实例化bean）
     */
    protected void refresh() throws Exception{
        loadBeanDefinitions(beanFactory);
        registerBeanPostProcessors(beanFactory);
        onRefresh();
    }

    protected abstract void loadBeanDefinitions(AbstractBeanFactory beanFactory) throws Exception;

    /**
     * 实例化bean
     *
     * 调用beanFactory的批量实例化逻辑
     */
    protected void onRefresh() throws Exception{
        beanFactory.preInstantiateSingletons();
    }



    /**
     * 将bean容器中的BeanPostProcessor实现类，注册到bean处理逻辑列表
     */
    public void registerBeanPostProcessors(AbstractBeanFactory beanFactory) throws Exception {
        List beanPostProcessors = beanFactory.getBeansByType(BeanPostProcessor.class);
        for (Object beanPostProcessor : beanPostProcessors) {
            beanFactory.addBeanPostProcessor((BeanPostProcessor) beanPostProcessor);
        }
    }

}
